#ifndef PD_DPM_PRV_H_INCLUDED
#define PD_DPM_PRV_H_INCLUDED

#include "common.h"

#define SVID_DATA_LOCAL_MODE(svid_data, n)	(svid_data->local_mode.mode_vdo[n])
#define SVID_DATA_REMOTE_MODE(svid_data, n) (svid_data->remote_mode.mode_vdo[n])
#define SVID_DATA_DFP_GET_ACTIVE_MODE(svid_data) SVID_DATA_REMOTE_MODE(svid_data, svid_data->active_mode-1)
#define SVID_DATA_UFP_GET_ACTIVE_MODE(svid_data) SVID_DATA_LOCAL_MODE(svid_data, svid_data->active_mode-1)

enum {
	GOOD_PW_NONE = 0,	/* both no GP */
	GOOD_PW_PARTNER,	/* partner has GP */
	GOOD_PW_LOCAL,		/* local has GP */
	GOOD_PW_BOTH,		/* both have GPs */
};

int dpm_check_good_power(struct pd_port *pd_port);
/* SVDM */
struct svdm_svid_data *dpm_get_svdm_svid_data(struct pd_port *pd_port, uint16_t svid);
struct svdm_svid_data *dpm_get_svdm_svid_data_via_cable_svids(struct pd_port *pd_port, uint16_t svid);
bool svdm_reset_state(struct pd_port *pd_port);
bool svdm_notify_pe_startup(struct pd_port *pd_port);
bool dpm_check_data_msg_event(struct pd_port *pd_port, uint8_t msg);
bool dpm_check_ext_msg_event(struct pd_port *pd_port, uint8_t msg);
int dpm_vdm_reply_svdm_request(struct pd_port *pd_port, bool ack);
int dpm_vdm_reply_svdm_nak(struct pd_port *pd_port);
bool svdm_notify_pe_ready(struct pd_port *pd_port);
bool svdm_notify_pe_shutdown(struct pd_port *pd_port);
bool dp_notify_pe_shutdown(struct pd_port *pd_port, struct svdm_svid_data *svid_data);
bool svdm_dfp_inform_id(struct pd_port *pd_port, bool ack);
bool dp_dfp_u_notify_discover_svids(struct pd_port *pd_port, struct svdm_svid_data *svid_data, bool ack);
bool svdm_dfp_inform_svids(struct pd_port *pd_port, bool ack);
bool dp_dfp_u_notify_discover_modes(struct pd_port *pd_port, struct svdm_svid_data *svid_data, bool ack);
bool svdm_dfp_inform_modes(struct pd_port *pd_port, uint16_t svid, bool ack);
bool dp_dfp_u_notify_enter_mode(struct pd_port *pd_port,struct svdm_svid_data *svid_data, uint8_t ops, bool ack);
bool svdm_dfp_inform_enter_mode(struct pd_port *pd_port, uint16_t svid, uint8_t ops, bool ack);
bool dp_dfp_u_notify_exit_mode(struct pd_port *pd_port, struct svdm_svid_data *svid_data, uint8_t ops);
bool svdm_dfp_inform_exit_mode(struct pd_port *pd_port, uint16_t svid, uint8_t ops);
bool dp_dfp_u_notify_attention(struct pd_port *pd_port,struct svdm_svid_data *svid_data);
bool svdm_dfp_inform_attention(struct pd_port *pd_port, uint16_t svid);
bool dp_ufp_u_request_enter_mode(struct pd_port *pd_port, struct svdm_svid_data *svid_data, uint8_t ops);
bool svdm_ufp_request_enter_mode(struct pd_port *pd_port, uint16_t svid, uint8_t ops);
bool dp_ufp_u_request_exit_mode(struct pd_port *pd_port, struct svdm_svid_data *svid_data, uint8_t ops);
bool svdm_ufp_request_exit_mode(struct pd_port *pd_port, uint16_t svid, uint8_t ops);

static inline uint8_t dpm_vdm_get_ops(struct pd_port *pd_port)
{
	return pd_port->curr_vdm_ops;
}

static inline uint16_t dpm_vdm_get_svid(struct pd_port *pd_port)
{
	return pd_port->curr_vdm_svid;
}

static inline bool svdm_dfp_inform_cable_id(struct pd_port *pd_port, bool ack, uint32_t *payload, uint8_t cnt)
{
	int i;
	bool ret = false;
	struct svdm_svid_data *svid_data;

	for (i = 0; i < pd_port->svid_data_cnt && !ret; i++) {
		svid_data = &pd_port->svid_data[i];
		if (!svid_data->ops || !svid_data->ops->dfp_inform_cable_id)
			continue;
		ret = svid_data->ops->dfp_inform_cable_id(pd_port, svid_data,
							  ack, payload, cnt);
	}

	return ret;
}

static inline bool svdm_dfp_inform_cable_svids(struct pd_port *pd_port,
					       bool ack, uint32_t *payload,
					       uint8_t cnt)
{
	// log_i("svdm_dfp_inform_cable_svids\n");
	/*int i;
	bool ret = false;
	struct svdm_svid_data *svid_data;

	for (i = 0; i < pd_port->svid_data_cnt && !ret; i++) {
		svid_data = &pd_port->svid_data[i];
		if (!svid_data->ops || !svid_data->ops->dfp_inform_cable_svids)
			continue;
		ret = svid_data->ops->dfp_inform_cable_svids(pd_port, svid_data,
							     ack, payload, cnt);
	}

	return ret;*/
	return false;
}

static inline bool svdm_dfp_inform_cable_modes(struct pd_port *pd_port,
					       uint16_t svid, bool ack,
					       uint32_t *payload, uint8_t cnt)
{
	// log_i("svdm_dfp_inform_cable_modes\n");
	/*bool ret = false;
	struct svdm_svid_data *svid_data;

	svid_data = dpm_get_svdm_svid_data_via_cable_svids(pd_port, svid);
	if (svid_data == NULL)
		goto out;

	if (svid_data->ops && svid_data->ops->dfp_inform_cable_modes)
		ret = svid_data->ops->dfp_inform_cable_modes(pd_port, svid_data,
							     ack, payload, cnt);
out:
	return ret;*/
	return false;
}

#endif /* PD_DPM_PRV_H_INCLUDED */

